home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 April: Mac OS SDK / Dev.CD Apr 99 SDK1.toast / Development Kits / ContextualMenuManagerSDK 1.0.3 / Contextual Menu Development / ContextTypeCMPlugin (Sample) / ContextTypeCMPlugin.cp < prev    next >
Encoding:
Text File  |  1998-01-27  |  8.4 KB  |  305 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        ContextTypeCMPlugin.cp
  3.  
  4.     Contains:    <contents>
  5.  
  6.     Written by:    Guy Fullerton
  7.  
  8.     Copyright:    <copyright>
  9.  
  10.     Change History (most recent first):
  11.  
  12.          <4>     1/16/97    GBF     Updating for Direct to SOM. Adding fragment initializer.
  13.          <3>     4/12/96    GBF     The parameters for ExamineContext had changed.
  14.          <2>     3/22/96    GBF     Added outNeedMoreTime parameter to ExamineContext
  15.          <1>     3/14/96    GBF     first checked in
  16. */
  17.  
  18.  
  19. // Class Header
  20. #include "ContextTypeCMPlugin.h"
  21.  
  22. // Mac OS Includes
  23. #include <AERegistry.h>
  24. #include <CodeFragments.h>
  25. #include <ContextualMenuPlugins.h>
  26.  
  27. // SOM Includes
  28. #include <som.xh>
  29.  
  30.  
  31.  
  32. // Function declarations
  33. extern pascal OSErr __initialize(CFragInitBlockPtr); // metrowerks's default initializer
  34. extern pascal void __terminate(void);
  35. pascal OSErr ContextTypeCMPluginInitialize(CFragInitBlockPtr init); // our initializer
  36. pascal void ContextTypeCMPluginTerminate(void); // our terminator
  37. OSStatus AddCommandToAEDescList(ConstStr255Param inCommandString,
  38.     SInt32 inCommandID, AEDescList* ioCommandList);
  39. OSStatus CreateSampleSubmenu(AEDescList* ioCommandList);
  40.  
  41.  
  42.  
  43. /*******************************************************************************
  44.  
  45.     ContextTypeCMPluginInitialize
  46.     
  47.         All plugin SOM object must somehow register themselves so clients
  48.         can instantiate them by name.  The best place that I've found to
  49.         do it is in the fragment initializer.
  50.  
  51. *******************************************************************************/
  52.  
  53. pascal OSErr ContextTypeCMPluginInitialize(CFragInitBlockPtr init)
  54. {
  55. #pragma unused (init)
  56.  
  57.     OSErr theError = __initialize(init);
  58.     if (theError == noErr)
  59.     {
  60.         // register our class with SOM
  61.         somNewClass(ContextTypeCMPlugin);
  62.     }
  63.  
  64.     return theError;
  65.     
  66. } // ContextTypeCMPluginInitialize
  67.  
  68.  
  69.  
  70. /*******************************************************************************
  71.  
  72.     ContextTypeCMPlugin::Initialize
  73.  
  74. *******************************************************************************/
  75.  
  76. OSStatus  ContextTypeCMPlugin::Initialize(
  77.     Environment*,
  78.     FSSpec* inFileSpec)
  79. {
  80. #pragma unused (inFileSpec)
  81.  
  82.     // we don't need to do anything special here
  83.  
  84.     return noErr;
  85.     
  86. } // ContextTypeCMPlugin::Initialize
  87.  
  88.  
  89.  
  90. /*******************************************************************************
  91.  
  92.     ContextTypeCMPlugin::ExamineContext
  93.  
  94. *******************************************************************************/
  95.  
  96. OSStatus  ContextTypeCMPlugin::ExamineContext(
  97.     Environment*,
  98.     AEDesc *inContextDescriptor,
  99.     SInt32 inTimeOutInTicks,
  100.     AEDescList* ioCommands,
  101.     Boolean* outNeedMoreTime)
  102. {
  103. #pragma unused(inTimeOutInTicks)
  104.     
  105.     // this is a quick sample that looks for text in the context descriptor
  106.     
  107.     // make sure the descriptor isn't null
  108.     if (inContextDescriptor != NULL)
  109.     {
  110.         // tell the raw type of the descriptor
  111.         Str15 theDescriptorType;
  112.         theDescriptorType[0] = 4;
  113.         *(DescType*)(&theDescriptorType[1]) = inContextDescriptor->descriptorType;
  114.         ::AddCommandToAEDescList(theDescriptorType, 1, ioCommands);
  115.         
  116.         // try to get text out of the context descriptor; make sure to
  117.         // coerce it, cuz the app may have passed an object specifier or
  118.         // styled text, etc.
  119.         AEDesc theTextDesc = { typeNull, NULL };
  120.         if (::AECoerceDesc(inContextDescriptor, typeChar, &theTextDesc) == noErr)
  121.         {
  122.             // add a text only command to our command list
  123.             ::AddCommandToAEDescList("\pWe got text!", 2, ioCommands);
  124.         }
  125.         ::AEDisposeDesc(&theTextDesc);
  126.         
  127.         // Just for kicks, lets create a submenu for our plugin
  128.         ::CreateSampleSubmenu(ioCommands);
  129.     }
  130.     else
  131.     {
  132.         // we have a null descriptor
  133.         ::AddCommandToAEDescList("\pNULL Descriptor", 3, ioCommands);
  134.     }
  135.     
  136.     *outNeedMoreTime = false;
  137.     
  138.     return noErr;
  139.     
  140. } // ContextTypeCMPlugin::ExamineContext
  141.  
  142.  
  143.  
  144. /*******************************************************************************
  145.  
  146.     ContextTypeCMPlugin::HandleSelection
  147.  
  148. *******************************************************************************/
  149.  
  150. OSStatus ContextTypeCMPlugin::HandleSelection(
  151.     Environment*,
  152.     AEDesc *inContextDescriptor,
  153.     SInt32 inCommandID)
  154. {
  155. #pragma unused (inContextDescriptor, inCommandID)
  156.  
  157.     // here is where you would actually carry out the action that the user
  158.     // requested.
  159.     
  160.     return noErr;
  161.     
  162. } // ContextTypeCMPlugin::HandleSelection
  163.  
  164.  
  165.  
  166. /*******************************************************************************
  167.  
  168.     ContextTypeCMPlugin::PostMenuCleanup
  169.  
  170. *******************************************************************************/
  171.  
  172. OSStatus ContextTypeCMPlugin::PostMenuCleanup(
  173.     Environment*)
  174. {
  175.     // we didn't allocate any buffers or cache any data in ExamineContext,
  176.     // so we don't need to clean anything up here
  177.     
  178.     return noErr;
  179.     
  180. } // ContextTypeCMPlugin::PostMenuCleanup
  181.  
  182.  
  183.  
  184. /*******************************************************************************
  185.  
  186.     AddCommandToAEDescList
  187.  
  188. *******************************************************************************/
  189.  
  190. OSStatus AddCommandToAEDescList(
  191.     ConstStr255Param inCommandString,
  192.     SInt32 inCommandID,
  193.     AEDescList* ioCommandList)
  194. {
  195.     OSStatus theError = noErr;
  196.     
  197.     AERecord theCommandRecord = { typeNull, NULL };
  198.     
  199.     do
  200.     {
  201.         // create an apple event record for our command
  202.         theError = ::AECreateList(NULL, 0, true, &theCommandRecord);
  203.         if (theError != noErr) break;
  204.         
  205.         // stick the command text into the aerecord
  206.         theError = ::AEPutKeyPtr(&theCommandRecord, keyAEName, typeChar,
  207.             &inCommandString[1], inCommandString[0]);
  208.         if (theError != noErr) break;
  209.             
  210.         // stick the command ID into the AERecord
  211.         theError = ::AEPutKeyPtr(&theCommandRecord, keyContextualMenuCommandID, typeLongInteger,
  212.             &inCommandID, sizeof (inCommandID));
  213.         if (theError != noErr) break;
  214.         
  215.         // stick this record into the list of commands that we are passing back to CMM
  216.         theError = ::AEPutDesc(ioCommandList, // the list we're putting our command into
  217.                         0, // stick this command onto the end of our list
  218.                         &theCommandRecord); // the command I'm putting into the list
  219.         
  220.     } while (false);
  221.     
  222.     // clean up after ourself; dispose of the AERecord
  223.     AEDisposeDesc(&theCommandRecord);
  224.  
  225.     return theError;
  226.     
  227. } // AddCommandToAEDescList
  228.  
  229.  
  230.  
  231. /*******************************************************************************
  232.  
  233.     CreateSampleSubmenu
  234.  
  235. *******************************************************************************/
  236.  
  237. OSStatus CreateSampleSubmenu(AEDescList* ioCommandList)
  238. {
  239.     OSStatus theError = noErr;
  240.     
  241.     AEDescList theSubmenuCommands = { typeNull, NULL };
  242.     AERecord theSupercommand = { typeNull, NULL };
  243.     
  244.     do
  245.     {
  246.         // the first thing we should do is create an AEDescList of
  247.         // subcommands
  248.         {
  249.             // set up the AEDescList
  250.             theError = ::AECreateList(NULL, 0, false, &theSubmenuCommands);
  251.             if (theError != noErr) break;
  252.  
  253.             // stick some commands in this subcommand list
  254.             theError = ::AddCommandToAEDescList("\pSubcommand 1", 1001, &theSubmenuCommands);
  255.             if (theError != noErr) break;
  256.             
  257.             // another
  258.             theError = ::AddCommandToAEDescList("\pAnother Subcommand", 1002, &theSubmenuCommands);
  259.             if (theError != noErr) break;
  260.             
  261.             // yet another
  262.             theError = ::AddCommandToAEDescList("\pLast One", 1003, &theSubmenuCommands);
  263.             if (theError != noErr) break;
  264.         }
  265.         
  266.         // now, we need to create the supercommand which will "own" the
  267.         // subcommands.  The supercommand lives in the root command list.
  268.         // this looks very much like the AddCommandToAEDescList function,
  269.         // except that instead of putting a command ID in the record,
  270.         // we put in the subcommand list.
  271.         {
  272.             // create an apple event record for our supercommand
  273.             theError = ::AECreateList(NULL, 0, true, &theSupercommand);
  274.             if (theError != noErr) break;
  275.             
  276.             // stick the command text into the aerecord
  277.             Str255 theSupercommandText = "\pSubmenu Here";
  278.             theError = ::AEPutKeyPtr(&theSupercommand, keyAEName, typeChar,
  279.                 &theSupercommandText[1], theSupercommandText[0]);
  280.             if (theError != noErr) break;
  281.             
  282.             // stick the subcommands into into the AERecord
  283.             theError = ::AEPutKeyDesc(&theSupercommand, keyContextualMenuSubmenu,
  284.                 &theSubmenuCommands);
  285.             if (theError != noErr) break;
  286.             
  287.             // stick the supercommand into the list of commands that we are passing back to CMM
  288.             theError = ::AEPutDesc(ioCommandList, // the list we're putting our command into
  289.                             0, // stick this command onto the end of our list
  290.                             &theSupercommand); // the command I'm putting into the list
  291.         }
  292.     }
  293.     while (false);
  294.     
  295.     // clean up after ourself
  296.     AEDisposeDesc(&theSubmenuCommands);
  297.     AEDisposeDesc(&theSupercommand);
  298.  
  299.     return theError;
  300.     
  301. } // CreateSampleSubmenu
  302.  
  303.  
  304.  
  305.